package com.dragon.flow.service.flowable.impl;

import com.dragon.flow.enm.flowable.CommentTypeEnum;
import com.dragon.flow.exception.FlowPlusException;
import com.dragon.flow.service.flowable.BaseFlowableService;
import com.dragon.flow.service.flowable.FlowableTaskOperateService;
import com.dragon.flow.vo.task.PlusCompleteTaskVo;
import com.dragon.tools.common.ReturnCode;
import com.dragon.tools.common.UUIDGenerator;
import com.dragon.tools.vo.ReturnVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.task.api.DelegationState;
import org.flowable.task.api.Task;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @title:
 * @author: bruce.liu
 * @since: 2024/6/24 13:33
 */
@Slf4j
@Service
@Transactional
public class FlowableTaskOperateServiceImpl extends BaseFlowableService implements FlowableTaskOperateService {
    @Override
    public ReturnVo<String> completeTask(PlusCompleteTaskVo completeTaskVo) throws FlowPlusException {
        ReturnVo<String> returnVo = new ReturnVo<>(ReturnCode.FAIL, "审批失败！");
        try {
            if (completeTaskVo != null && StringUtils.isNotBlank(completeTaskVo.getTaskId())) {
                TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(completeTaskVo.getTaskId()).singleResult();
                if (task != null) {
                    //如果流程实例的id为空就设置成任务的流程实例id
                    if (StringUtils.isBlank(completeTaskVo.getProcessInstanceId())) {
                        completeTaskVo.setProcessInstanceId(task.getProcessInstanceId());
                    }
                    String taskId = completeTaskVo.getTaskId();
                    completeTaskVo.setTaskId(taskId);
                    //创建临时变量
                    Map<String, Object> transientVariables = this.transientVariables(completeTaskVo);
                    //2.委派处理
                    if (DelegationState.PENDING.equals(task.getDelegationState())) {
                        //2.1生成历史记录
                        Task subTask = this.createSubTask(task, task.getParentTaskId(), completeTaskVo.getUserCode());
                        taskId = subTask.getId();
                        //1.添加审批意见和修改流程状态
                        completeTaskVo.setTaskId(taskId);
                        completeTaskVo.setActivityId(task.getTaskDefinitionKey());
                        completeTaskVo.setActivityName(task.getName());
                        taskService.complete(subTask.getId(), null, transientVariables);
                        //2.2执行委派
                        taskService.resolveTask(completeTaskVo.getTaskId(), completeTaskVo.getVariables());
                    } else {
                        //1.添加审批意见和修改流程状态
                        completeTaskVo.setTaskId(taskId);
                        completeTaskVo.setActivityId(task.getTaskDefinitionKey());
                        completeTaskVo.setActivityName(task.getName());
                        //2.正常任务结束 修改历史数据
                        if (StringUtils.isBlank(task.getAssignee())) {
                            List<IdentityLink> identityLinks = taskService.getIdentityLinksForTask(taskId);
                            if (CollectionUtils.isNotEmpty(identityLinks)) {
                                taskService.claim(taskId, completeTaskVo.getUserCode());
                            }
                        }
                        //审批任务
                        taskService.setAssignee(completeTaskVo.getTaskId(), completeTaskVo.getUserCode());
                        taskService.complete(completeTaskVo.getTaskId(), completeTaskVo.getVariables(), transientVariables);
                        //3.处理父任务
                        String parentTaskId = task.getParentTaskId();
                        if (StringUtils.isNotBlank(parentTaskId)) {
                            String tableName = managementService.getTableName(TaskEntity.class);
                            String sql = "select count(1) from " + tableName + " where PARENT_TASK_ID_=#{parentTaskId}";
                            long subTaskCount = taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).count();
                            if (subTaskCount == 0) {
                                Task ptask = taskService.createTaskQuery().taskId(parentTaskId).singleResult();
                                //处理前后加签的任务
                                taskService.resolveTask(parentTaskId);
                                if (CommentTypeEnum.HJQ.toString().equals(ptask.getScopeType())) {
                                    //审批任务
                                    taskService.setAssignee(parentTaskId, completeTaskVo.getUserCode());
                                    taskService.complete(parentTaskId, completeTaskVo.getVariables(), transientVariables);
                                }
                            }
                        }
                    }
                    returnVo.setCode(ReturnCode.SUCCESS);
                    returnVo.setMsg("审批成功！");
                } else {
                    returnVo = new ReturnVo<>(ReturnCode.FAIL, "任务已审批，请确认!");
                }
            } else {
                returnVo.setMsg("任务ID不能为空！");
            }
        } catch (Exception e) {
            log.error("审批任务报错！原因：", e);
            returnVo.setMsg("审批失败！原因：" + e.getMessage());
        }
        return returnVo;
    }

    /**
     * 添加瞬时变量 添加下一审批人或者线的临时变量
     *
     * @param completeTaskVo 审批参数
     * @return
     */
    private Map<String, Object> transientVariables(PlusCompleteTaskVo completeTaskVo) {
        Map<String, Object> transientVariables = new HashMap<>();
        if (completeTaskVo.getNextSequenceFlow() != null && CollectionUtils.isNotEmpty(completeTaskVo.getNextSequenceFlow().getValues())) {
            transientVariables.put(completeTaskVo.getNextSequenceFlow().getCode(), completeTaskVo.getNextSequenceFlow().getValues().get(0));
        }
        if (CollectionUtils.isNotEmpty(completeTaskVo.getNextUsers())) {
            completeTaskVo.getNextUsers().forEach(nextSequenceUserVo -> {
                if (StringUtils.isNotBlank(nextSequenceUserVo.getCode())) {
                    List<String> values = nextSequenceUserVo.getValues();
                    if (CollectionUtils.isNotEmpty(values)) {
                        if (values.size() > 1) {
                            transientVariables.put(nextSequenceUserVo.getCode(), values);
                        } else {
                            transientVariables.put(nextSequenceUserVo.getCode(), values.get(0));
                        }
                    }
                }
            });
        }
        return transientVariables;
    }

    /**
     * 创建任务
     *
     * @param assignee 任务的执行者
     * @param ptask    父亲任务实体
     * @param ptaskId  父亲id
     * @return
     */
    private Task createSubTask(TaskEntity ptask, String ptaskId, String assignee) {
        TaskEntity task = null;
        if (ptask != null) {
            task = (TaskEntity) taskService.newTask(UUIDGenerator.generate());
            task.setAssignee(assignee);
            task.setProcessInstanceId(ptask.getProcessInstanceId());
            task.setProcessDefinitionId(ptask.getProcessDefinitionId());
            task.setParentTaskId(ptaskId);
            task.setCategory(ptask.getCategory());
            task.setDescription(ptask.getDescription());
            task.setName(ptask.getName());
            task.setTaskDefinitionKey(ptask.getTaskDefinitionKey());
            task.setTaskDefinitionId(ptask.getTaskDefinitionId());
            task.setTenantId(ptask.getTenantId());
            task.setCreateTime(new Date());
            task.setPriority(ptask.getPriority());
            taskService.saveTask(task);
        }
        return task;
    }
}
